﻿using UnityEngine;
using UnityEditor;
using Framework.Extension.UI;
using Framework.Extension.UI.LoopList;

[CustomEditor(typeof(LoopListEx))]
public class LoopListExEditor : UnityEditor.Editor
{
    private string[] directionSelection;
    private const int Vertical = (int)LoopListEx.Direction.Vertical;
    private const int Horizontal = (int)LoopListEx.Direction.Horizontal;

    private string[] slotSizeModeSelection;
    private const int Fixed = (int)LoopListEx.SlotSizeMode.Fixed;
    private const int Variant = (int)LoopListEx.SlotSizeMode.Variant;
    private static string[] excludingPropertyNames;

    private const string DirectionPropertyName = "direction";
    private const string SlotPrefabPropertyName = "slotPrefab";
    private const string SlotSizeModePropertyName = "slotSizeMode";
    private const string SlotSizePropertyName = "slotSize";
    private const string SlotOffsetPropertyName = "slotOffset";
    private const string CountPerRowPropertyName = "countPerRow";
    private const string InvertPropertyName = "invert";
    private const string UpdateCountPerFramePropertyName = "updateCountPerFrame";

    private GUIStyle regionStyle;

    private bool slotRegionShow = true;

    private void OnEnable()
    {
        directionSelection = System.Enum.GetNames(typeof(LoopListEx.Direction));
        slotSizeModeSelection = System.Enum.GetNames(typeof(LoopListEx.SlotSizeMode));
        excludingPropertyNames = new string[]{
            DirectionPropertyName,
            SlotSizePropertyName,
            SlotPrefabPropertyName,
            SlotSizePropertyName,
            SlotOffsetPropertyName,
            CountPerRowPropertyName,
            InvertPropertyName,
            UpdateCountPerFramePropertyName,
        };
    }

    private void InitStyle()
    {
        if (regionStyle != null) return;
        regionStyle = new GUIStyle(EditorStyles.foldout);

#if UNITY_STANDALONE_WIN
        regionStyle.fontStyle = FontStyle.Bold;
#endif
    }

    public override void OnInspectorGUI()
    {
        EditorGUI.BeginDisabledGroup(true);
        DrawPropertiesExcluding(serializedObject, excludingPropertyNames);
        EditorGUI.EndDisabledGroup();

        var directionProperty = serializedObject.FindProperty(DirectionPropertyName);
        int directionIndex = GUILayout.Toolbar(directionProperty.enumValueIndex, directionSelection);
        directionProperty.enumValueIndex = directionIndex;

        var slotSizeModeProperty = serializedObject.FindProperty(SlotSizeModePropertyName);
        int slotSizeModeIndex = GUILayout.Toolbar(slotSizeModeProperty.enumValueIndex, slotSizeModeSelection);
        slotSizeModeProperty.enumValueIndex = slotSizeModeIndex;

        var countPerRowProperty = serializedObject.FindProperty(CountPerRowPropertyName);
        if(slotSizeModeIndex == Variant)
        {
            EditorGUI.BeginDisabledGroup(true);
            countPerRowProperty.intValue = EditorGUILayout.IntSlider(new GUIContent(directionIndex == Vertical ? "Count / Row" : "Count / Col"), 1, 1, 10);
            EditorGUI.EndDisabledGroup();
        }
        else
        {
            countPerRowProperty.intValue = EditorGUILayout.IntSlider(new GUIContent(directionIndex == Vertical ? "Count / Row" : "Count / Col"), countPerRowProperty.intValue, 1, 10);
        }

        var invertProperty = serializedObject.FindProperty(InvertPropertyName);
        EditorGUILayout.PropertyField(invertProperty);

        var updateCountPerFrameProperty = serializedObject.FindProperty(UpdateCountPerFramePropertyName);
        EditorGUILayout.PropertyField(updateCountPerFrameProperty, new GUIContent("Update / Frame"));

        InitStyle();
        EditorGUILayout.BeginVertical("GroupBox");

        EditorGUI.indentLevel++;
        slotRegionShow = EditorGUILayout.Foldout(slotRegionShow, "Slot", regionStyle);
        EditorGUI.indentLevel--;

        if(slotRegionShow)
        {
            var slotPrefabProperty = serializedObject.FindProperty(SlotPrefabPropertyName);
            var preSlotPrefab = slotPrefabProperty.objectReferenceValue;
            EditorGUILayout.PropertyField(slotPrefabProperty, new GUIContent("Prefab"));
            var slotPrefab = slotPrefabProperty.objectReferenceValue;

            Vector2 newSlotSize = Vector2.zero;

            if(slotPrefab != preSlotPrefab && slotPrefab is GameObject)
            {
                var rectTransform = (slotPrefab as GameObject).GetComponent<RectTransform>();
                if(rectTransform) newSlotSize = rectTransform.rect.size;
            }

            //if(slotSizeModeIndex == Fixed)
            {
                var slotSizeProperty = serializedObject.FindProperty(SlotSizePropertyName);
                if (newSlotSize != Vector2.zero) slotSizeProperty.vector2Value = newSlotSize;

                EditorGUILayout.BeginHorizontal();
                GUILayout.Label("Size", GUILayout.Width(45f));
                slotSizeProperty.vector2Value = EditorGUILayout.Vector2Field("", slotSizeProperty.vector2Value, GUILayout.Height(17f));
                EditorGUILayout.EndHorizontal();
            }

            var slotOffsetProperty = serializedObject.FindProperty(SlotOffsetPropertyName);

            EditorGUILayout.BeginHorizontal();
            GUILayout.Label("Offset", GUILayout.Width(45f));
            slotOffsetProperty.vector2Value = EditorGUILayout.Vector2Field("", slotOffsetProperty.vector2Value, GUILayout.Height(17f));
            EditorGUILayout.EndHorizontal();
        }

        EditorGUILayout.EndVertical();

        serializedObject.ApplyModifiedProperties();
    }

}
